package com.michale.framework.security.service.impl;


import com.michale.common.domain.permissions.UserEntity;
import com.michale.common.domain.security.LoginUserDetail;
import com.michale.common.enmus.UserStatus;
import com.michale.common.exception.ServiceException;
import com.michale.common.utils.String.StringUtils;
import com.michale.framework.security.service.PasswordService;
import com.michale.framework.security.service.PermissionService;
import com.michale.system.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Set;

/**
 * @author Michale
 * @apiNote 用户详细信息服务包含
 */
@Slf4j
@Service("userDetailsServiceImpl")
public class UserDetailsServiceImpl implements UserDetailsService {

    @Resource
    private UserService userService;
    @Resource
    private PasswordService passwordService;
    @Resource
    private PermissionService permissionService;

    /**
     * 根据用户名定位用户
     * 在实际实现中，搜索可能区分大小写或不区分大小写，具体取决于实现实例的配置方式
     *
     * @param userName 标识需要其数据的用户的用户名
     * @return 完全填充的用户记录
     */
    @Override
    public UserDetails loadUserByUsername(String userName) {
        UserEntity userEntity = userService.selectUserByUserName(userName);
        if (StringUtils.isNull(userEntity)) {
            log.info("登录用户：{} 不存在.", userName);
            throw new ServiceException("用户验证处理", "登录用户：" + userName + " 不存在");
        } else if (UserStatus.DELETED.getCode().equals(userEntity.getDelFlag())) {
            log.info("登录用户：{} 已被删除.", userName);
            throw new ServiceException("对不起，您的账号：" + userName + " 已被删除");
        } else if (UserStatus.DISABLE.getCode().equals(userEntity.getStatus())) {
            log.info("登录用户：{} 已被停用.", userName);
            throw new ServiceException("用户验证处理", "对不起，您的账号：" + userName + " 已停用");
        }
        //自定义比对密码(通过用户名查询到的用户信息)
        passwordService.validate(userEntity);
        //创建用户对象存入到Authorities
        return createLoginUser(userEntity);
    }

    /**
     * @param userEntity 用户信息
     * @return 用户详细信息
     */
    public UserDetails createLoginUser(UserEntity userEntity) {
        //获取菜单权限信息
        Set<String> menuPermission = permissionService.getMenuPermission(userEntity);
        return new LoginUserDetail(userEntity.getUserId(), userEntity.getDeptId(), userEntity, menuPermission);
    }
}


